/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package treegenerator.gui;

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.net.URL;
import javax.swing.Box;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListModel;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import org.openide.filesystems.FileUtil;
import org.xml.sax.SAXException;

/**
 *
 * @author jannes
 */
public class TreeListPanel extends JPanel{
    private JList treeList;
    private MainPanel mainPanel;    
    public TreeListPanel(MainPanel mainPanel_){
        super(new BorderLayout());        
        mainPanel = mainPanel_;
        JLabel lblTitle = new JLabel("Tree list");
        lblTitle.setFont(new Font(lblTitle.getFont().getName(), Font.BOLD, 20));
        Box hb = Box.createHorizontalBox();        
        hb.add(Box.createHorizontalGlue());
        hb.add(lblTitle);
        hb.add(Box.createHorizontalGlue());
        add(hb,BorderLayout.NORTH);
        ListModel model = new DefaultListModel();
        treeList = new JList(model);        
        add(new JScrollPane(treeList),BorderLayout.CENTER);        
        resetList();
        treeList.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent me) {
                if(me.getClickCount() == 2){
                    mainPanel.loadTree((File)treeList.getSelectedValue());
                }                
            }
        });  
        Box b = Box.createVerticalBox();
        add(b,BorderLayout.SOUTH);
        
        JButton btnSaveTree = new JButton("Save");
        b.add(btnSaveTree);
        btnSaveTree.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {                                                        
                mainPanel.getXMLViewer().saveXML();
                FileWriter fw = null;                
                try{                                            
                    fw = new FileWriter(mainPanel.getOpenedTree());                        
                    BufferedWriter bw = new BufferedWriter(fw);
                    bw.write("<tree>");    
                    bw.newLine();
                    mainPanel.getTexturePanel().writeTextureParams(bw);
                    bw.newLine();
                    bw.write("</tree>");
                    bw.flush();
                }catch(Exception exc){
                    JOptionPane.showMessageDialog(null, "error saving tree xml: " + exc);
                }finally{
                    try{
                        fw.close();                        
                    }catch(Exception exc){}
                }    
                File textureDir = new File(mainPanel.getOpenedTree().getParentFile(),"Textures/" + mainPanel.getTreePanel().getTreeName());
                mainPanel.getTexturePanel().deletePreviousAndSaveTiles(textureDir);
            }
        });
        JButton btnNewTree = new JButton("New");
        b.add(btnNewTree);
        btnNewTree.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //collecting data;
                String name = JOptionPane.showInputDialog("Tree type name: ");                     
                File arbaroFile = null;                                          
                
                JFileChooser jfc = new JFileChooser();   
                jfc.setDialogTitle("Choose arbaro xml file");
                int result = jfc.showOpenDialog(null);                
                while(result == JFileChooser.APPROVE_OPTION 
                        && !mainPanel.getXMLViewer().checkXML(jfc.getSelectedFile())){
                    result = jfc.showOpenDialog(null);                
                }                                                
                if(result == JFileChooser.APPROVE_OPTION){
                    arbaroFile = jfc.getSelectedFile();
                }
                //writing data;
                if(arbaroFile != null && name != null && !name.equals("")){
                    String settingsDir = System.getProperty("netbeans.user");
                    File basedir = new File(settingsDir);
                    basedir = new File(basedir,"TreeData/Trees/Definitions");                              
                    File newTree = new File(basedir, name + ".xml");
                    FileWriter fw = null;                
                    try{                                            
                        fw = new FileWriter(newTree);
                        BufferedWriter bw = new BufferedWriter(fw);
                        bw.write("<tree>");    
                        bw.newLine();
                        mainPanel.getTexturePanel().writeTextureParams(bw);
                        bw.newLine();
                        bw.write("</tree>");
                        bw.flush();
                    }catch(Exception exc){
                        JOptionPane.showMessageDialog(null, "error creating tree xml: " + exc);
                    }finally{
                        try{
                            fw.close();                        
                        }catch(Exception exc){}
                    }
                    try{
                        FileUtil.copyFile(FileUtil.createData(arbaroFile), FileUtil.createFolder(new File(basedir,"ArbaroFiles")), name);                    
                    }catch(Exception exc){
                        JOptionPane.showMessageDialog(null, "error copying arbaro file: " + exc);
                    }
                    File texturedir = new File(basedir,"Textures/" + name);
                    texturedir.mkdirs();
                    File dir = new File(texturedir,"Trunk");
                    dir.mkdirs();
                    dir = new File(texturedir,"Stem");
                    dir.mkdirs();
                    dir = new File(texturedir,"Leaf");
                    dir.mkdirs();
                    
                    mainPanel.getTreeListPanel().resetList();
                    mainPanel.loadTree(newTree);
                }                
            }
        });
        JButton btnRenameTree = new JButton("Rename");
        b.add(btnRenameTree);
        btnRenameTree.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String newName = JOptionPane.showInputDialog("New name: ");
                if(newName != null && !newName.equals("")){
                    mainPanel.renameTree(newName);
                }
            }
        });
        JButton btnRemoveTree = new JButton("Remove");
        b.add(btnRemoveTree);
        btnRemoveTree.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int result = JOptionPane.showConfirmDialog(null, "Do you want to remove the tree definition named: " + mainPanel.getOpenedTree().getName());
                if(result == JOptionPane.YES_OPTION){
                    mainPanel.removeTree();
                }
            }
        });
    }
    
    public void resetList(){
        ((DefaultListModel)treeList.getModel()).clear();
        File defDir = new File(mainPanel.getProjectDirectory(), "assets/Trees/Definitions");
        FilenameFilter ff = new FilenameFilter() {
            @Override
            public boolean accept(File file, String name) {
                return name.endsWith(".xml");
            }
        };
        for(File f : defDir.listFiles(ff)){
            if(checkXML(f)){
                try{
                    ((DefaultListModel)treeList.getModel()).addElement(new TreeFileFormatter(f));
                }catch(Exception exc){
                    JOptionPane.showMessageDialog(null, exc.getMessage());
                }
            }
        }        
    }
    
    public boolean checkXML(File file){              
        SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");                        
        try{            
            URL url = getClass().getResource("/treegenerator/treeDef.xsd");
            Schema schema = factory.newSchema(url);           
            Validator validator = schema.newValidator();                            
            Source source = new StreamSource(file);           
            try {
                validator.validate(source);
                return true;
            }
            catch (SAXException ex) {
                JOptionPane.showMessageDialog(null, "file is not valid because " + ex.getMessage());                                
                return false;
            }  
        }catch(Exception ex){            
            JOptionPane.showMessageDialog(null, "can't load shema");                                            
            return false;
        }
    }        
}
